module top (
	input clk,
	input reset,
	output [1:0] led
);

parameter DATA_WIDTH = 8;
parameter INT_SIZE = 8;
parameter RESULT_SIZE = 35;

wire reset_n;

reg opcode;
reg [DATA_WIDTH-1 : 0] a;
reg [DATA_WIDTH-1 : 0] b;
wire [DATA_WIDTH-1 : 0] r;
wire [DATA_WIDTH-1 : 0] add_r;
wire [(2*DATA_WIDTH)-1 : 0] mul_r;

wire [INT_SIZE-1 : 0] add_alpha;
wire add_alpha_valid;
wire [INT_SIZE-1 : 0] mul_alpha;
wire mul_alpha_valid;

wire [RESULT_SIZE - 1 : 0] estimate;
wire estimate_valid;

assign reset_n = ~reset;
assign led = {^r[7 : 4], ^r[3 : 0]};

always @(posedge clk) begin
	if (reset_n == 1'b0) begin
		opcode <= 1'b0;
		a <= 0;
		b <= 0;
	end else begin
		opcode <= !opcode;
		a <= a;
		b <= b;
		if (opcode == 1'b1) begin
			a <= a + 1;
			b <= b + 1;
		end
	end
end

alu #(.DATA_WIDTH (DATA_WIDTH)) alu_inst (
	.opcode(opcode),
	.a(a),
	.b(b),
	.add_r(add_r),
	.mul_r(mul_r),
	.r(r)
);

counter #(.DATA_WIDTH (DATA_WIDTH), .INT_SIZE (INT_SIZE)) counter_add_inst (
	.clk(clk),
	.reset_n(reset_n),
	.data(add_r),
	.alpha(add_alpha),
	.valid(add_alpha_valid)
);

counter #(.DATA_WIDTH (2*DATA_WIDTH), .INT_SIZE (INT_SIZE)) counter_mul_inst (
	.clk(clk),
	.reset_n(reset_n),
	.data(mul_r),
	.alpha(mul_alpha),
	.valid(mul_alpha_valid)
);

estimator #(.INT_SIZE (INT_SIZE), .RESULT_SIZE (RESULT_SIZE)) estimator_inst (
	.clk(clk),
	.add_alpha(add_alpha),
	.add_alpha_valid(add_alpha_valid),
	.mul_alpha(mul_alpha),
	.mul_alpha_valid(mul_alpha_valid),
	.estimate(estimate),
	.estimate_valid(estimate_valid)
);

/*
axi_uartlite_0 axi_uartlite (
	.s_axi_aclk(s_axi_aclk),        // input wire s_axi_aclk
	.s_axi_aresetn(s_axi_aresetn),  // input wire s_axi_aresetn
	.interrupt(interrupt),          // output wire interrupt
	.s_axi_awaddr(s_axi_awaddr),    // input wire [3 : 0] s_axi_awaddr
	.s_axi_awvalid(s_axi_awvalid),  // input wire s_axi_awvalid
	.s_axi_awready(s_axi_awready),  // output wire s_axi_awready
	.s_axi_wdata(s_axi_wdata),      // input wire [31 : 0] s_axi_wdata
	.s_axi_wstrb(s_axi_wstrb),      // input wire [3 : 0] s_axi_wstrb
	.s_axi_wvalid(s_axi_wvalid),    // input wire s_axi_wvalid
	.s_axi_wready(s_axi_wready),    // output wire s_axi_wready
	.s_axi_bresp(s_axi_bresp),      // output wire [1 : 0] s_axi_bresp
	.s_axi_bvalid(s_axi_bvalid),    // output wire s_axi_bvalid
	.s_axi_bready(s_axi_bready),    // input wire s_axi_bready
	.s_axi_araddr(s_axi_araddr),    // input wire [3 : 0] s_axi_araddr
	.s_axi_arvalid(s_axi_arvalid),  // input wire s_axi_arvalid
	.s_axi_arready(s_axi_arready),  // output wire s_axi_arready
	.s_axi_rdata(s_axi_rdata),      // output wire [31 : 0] s_axi_rdata
	.s_axi_rresp(s_axi_rresp),      // output wire [1 : 0] s_axi_rresp
	.s_axi_rvalid(s_axi_rvalid),    // output wire s_axi_rvalid
	.s_axi_rready(s_axi_rready),    // input wire s_axi_rready
	.rx(rx),                        // input wire rx
	.tx(tx)                        // output wire tx
);
*/

endmodule